package com.lw1throw.token.exception;

import cn.dev33.satoken.exception.*;
import com.alibaba.cola.dto.Response;
import com.alibaba.cola.exception.BizException;
import com.alibaba.cola.exception.SysException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.validation.BindException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.*;

import java.util.stream.Collectors;

/**
 * @ClassName: GlobalException.java
 * @Description:
 * @Author lw1throw
 * @date 2021/5/8
 */
@RestControllerAdvice
public class GlobalException {

    private static final Logger log = LoggerFactory.getLogger(GlobalException.class);

    /**
     * sa-token异常
     *
     * @param e
     * @return
     */
    @ExceptionHandler(value = {NotLoginException.class, NotRoleException.class, NotPermissionException.class,
            DisableLoginException.class, SaTokenException.class})
    public Response handleSaTokenException(Exception e) {
        log.error("token异常:{} 和 StackTrace:{}", e.getMessage(), e);
        if (e instanceof NotLoginException) {
            NotLoginException nle = (NotLoginException) e;
            return Response.buildFailure(nle.getType(), nle.getMessage());
        }
        if (e instanceof NotRoleException) {
            NotRoleException nre = (NotRoleException) e;
            return Response.buildFailure("A0300", "无此角色：" + nre.getRole());
        }
        if (e instanceof NotPermissionException) {
            NotPermissionException npe = (NotPermissionException) e;
            return Response.buildFailure("A0300", "无此权限：" + npe.getCode());
        }
        if (e instanceof DisableLoginException) {
            DisableLoginException dle = (DisableLoginException) e;
            return Response.buildFailure("A0202", "账号被封禁：" + dle.getDisableTime() + "秒后解封");
        }
        return Response.buildFailure("C0100", "token异常");
    }


    /**
     * 自定义业务异常
     *
     * @param e
     * @return
     */
    @ExceptionHandler(value = BizException.class)
    public Response handleBizException(BizException e) {
        log.error("业务异常:{} 和 StackTrace:{}", e.getMessage(), e);
        return Response.buildFailure(e.getErrCode(), e.getMessage());
    }

    /**
     * 自定义系统异常
     *
     * @param e
     * @return
     */
    @ExceptionHandler(value = SysException.class)
    public Response handleSysException(SysException e) {
        log.error("系统异常:{} 和 StackTrace:{}", e.getMessage(), e);
        return Response.buildFailure(e.getErrCode(), e.getMessage());
    }

    /**
     * 参数校验异常
     *
     * @param e
     * @throws BindException
     */
    @ExceptionHandler(value = {BindException.class, MethodArgumentNotValidException.class})
    public Response handleBindAndValidException(Exception e) {
        log.error("参数校验异常:{} 和 StackTrace:{}", e.getMessage(), e);
        if (e instanceof BindException) {
            BindException be = (BindException) e;
            String errorMsg = be.getBindingResult().getAllErrors().stream()
                    .map(objectError -> objectError.getDefaultMessage()).collect(Collectors.joining(","));
            return Response.buildFailure("A0400", errorMsg);
        }

        if (e instanceof MethodArgumentNotValidException) {
            MethodArgumentNotValidException manve = (MethodArgumentNotValidException) e;
            String errorMsg = manve.getBindingResult().getAllErrors().stream()
                    .map(objectError -> objectError.getDefaultMessage()).collect(Collectors.joining(","));
            return Response.buildFailure("A0400", errorMsg);
        }
        return Response.buildFailure("A0400", e.getMessage());
    }

    /**
     * 兜底异常
     *
     * @param e
     * @return
     */
    @ExceptionHandler(value = Exception.class)
    public Response handleException(Exception e) {
        log.error("异常:{} 和 StackTrace:{}", e.getMessage(), e);
        return Response.buildFailure("500", e.getMessage());
    }
}
